package com.ruoyi.recycle.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.recycle.constant.OrderInfoConstant;
import com.ruoyi.recycle.domain.*;
import com.ruoyi.recycle.dto.KuaiDiResultData;
import com.ruoyi.recycle.dto.KuaiDiResultDto;
import com.ruoyi.recycle.dto.RecycleOrderDTO;
import com.ruoyi.recycle.dto.deppon.request.JsonRootBean;
import com.ruoyi.recycle.dto.deppon.request.PackageInfo;
import com.ruoyi.recycle.dto.deppon.request.Receiver;
import com.ruoyi.recycle.dto.deppon.request.Sender;
import com.ruoyi.recycle.dto.deppon.response.ResultBeanResponse;
import com.ruoyi.recycle.dto.deppon.response.SynchronousDeBangStatus;
import com.ruoyi.recycle.mapper.*;
import com.ruoyi.recycle.service.ILogisticsExpenditureStatisticsService;
import com.ruoyi.recycle.service.IRecycleCommodityService;
import com.ruoyi.recycle.service.IRecycleOrderService;
import com.ruoyi.recycle.service.RecycleRequestLogService;
import com.ruoyi.recycle.utils.debang.FastJsonUtil;
import com.ruoyi.recycle.utils.HttpClientHelper;
import com.ruoyi.recycle.utils.OrderNoGenerateUtil;
import com.ruoyi.recycle.utils.debang.HttpUtils;
import com.ruoyi.recycle.utils.debang.ResultDO;
import com.ruoyi.recycle.utils.debang.SecurityUtil;
import com.ruoyi.recycle.vo.ClientServeOrderVO;
import com.ruoyi.recycle.vo.RecycleOrderVO;
import org.apache.commons.codec.digest.DigestUtils;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.apache.commons.codec.binary.Base64;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;

import org.apache.commons.httpclient.NameValuePair;

/**
 * 回收订单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-05-22
 */
@Service
@Transactional
public class RecycleOrderServiceImpl extends ServiceImpl<RecycleOrderMapper, RecycleOrder> implements IRecycleOrderService {
    @Autowired
    private RecycleOrderMapper recycleOrderMapper;
    @Autowired
    private IRecycleCommodityService recycleCommodityService;
    @Resource
    private RecycleCommodityMapper recycleCommodityMapper;
    @Autowired
    private OrderNoGenerateUtil orderNoGenerateUtil;
    @Resource
    private HousekeepingOrderMapper housekeepingOrderMapper;
    @Resource
    private ClientUserManagementMapper clientUserManagementMapper;
    @Resource
    private HousekeepingCommodityMapper housekeepingCommodityMapper;
    @Resource
    private AdminAddressMapper adminAddressMapper;
    @Resource
    private LogisticsExpenditureStatisticsMapper logisticsExpenditureStatisticsMapper;
    @Resource
    private SysTypeConfigMapper sysTypeConfigMapper;
    @Resource
    private PriceSettingMapper priceSettingMapper;
    @Resource
    private MerchantManagementMapper merchantManagementMapper;
    @Resource
    private IntegralConfigMapper integralConfigMapper;
    @Resource
    private MerchatBillRecordMapper merchatBillRecordMapper;
    @Resource
    private SalesmanManagementMapper salesmanManagementMapper;
    @Resource
    private ShopManagementMapper shopManagementMapper;
    @Resource
    private RecycleRequestLogService recycleRequestLogService;
    @Resource
    private ClientPrayerManagementMapper clientPrayerManagementMapper;
    //UAT
    //private final static String DEPPON_URL = "http://dpsanbox.deppon.com/sandbox-web/dop-standard-ewborder/createOrderNotify.action";
    private final static String COMPANY_CODE = "EWBGDHAHBK";
    private final static String SIGN = "BXBL";
    private final static String APP_KEY = "5ded13ec69eba019447e43e23470bdb0";
    private final static String TRANSPORT_TYPE = "PACKAGE";
    private final static String CUSTOMER_CODE = "955118799";
    //PROD
    private final static String DEPPON_URL = "http://gwapi.deppon.com/dop-interface-async/standard-order/createOrderNotify.action";



    /**
     * 查询回收订单
     *
     * @param recycleOrderNo 回收订单主键
     * @return 回收订单
     */
    @Override
    public RecycleOrderVO selectRecycleOrderById(String recycleOrderNo) {
        RecycleOrder recycleOrder = recycleOrderMapper.selectRecycleOrderById(recycleOrderNo);
        RecycleOrderVO recycleOrderVO = new RecycleOrderVO();
        BeanUtils.copyProperties(recycleOrder, recycleOrderVO);
        LogisticsExpenditureStatistics logisticsExpenditureStatistics = logisticsExpenditureStatisticsMapper.selectOne(
                new LambdaQueryWrapper<LogisticsExpenditureStatistics>().eq(LogisticsExpenditureStatistics::getLogisticsNumber, recycleOrderNo));
        if (!ObjectUtils.isEmpty(logisticsExpenditureStatistics)) {
            recycleOrderVO.setCourier(logisticsExpenditureStatistics.getCourier());
            recycleOrderVO.setCourierPhone(logisticsExpenditureStatistics.getCourierPhone());
        }
        return recycleOrderVO;
    }

    /**
     * 查询回收订单列表
     *
     * @param recycleOrder 回收订单
     * @return 回收订单
     */
    @Override
    public List<RecycleOrder> selectRecycleOrderList(RecycleOrder recycleOrder) {
        return recycleOrderMapper.selectRecycleOrderList(recycleOrder);
    }

    /**
     * 新增回收订单
     *
     * @param recycleOrder 回收订单
     * @return 结果
     */
    @Override
    public int insertRecycleOrder(RecycleOrder recycleOrder) {
        return recycleOrderMapper.insertRecycleOrder(recycleOrder);
    }

    /**
     * 修改回收订单
     *
     * @param recycleOrder 回收订单
     * @return 结果
     */
    @Override
    public int updateRecycleOrder(RecycleOrder recycleOrder) {
        return recycleOrderMapper.updateRecycleOrder(recycleOrder);
    }

    /**
     * 批量删除回收订单
     *
     * @param recycleOrderNos 需要删除的回收订单主键
     * @return 结果
     */
    @Override
    public int deleteRecycleOrderByIds(String[] recycleOrderNos) {
        return recycleOrderMapper.deleteRecycleOrderByIds(recycleOrderNos);
    }

    /**
     * 删除回收订单信息
     *
     * @param recycleOrderNo 回收订单主键
     * @return 结果
     */
    @Override
    public int deleteRecycleOrderById(String recycleOrderNo) {
        return recycleOrderMapper.deleteRecycleOrderById(recycleOrderNo);
    }


    @Override
    public List<RecycleCommodity> selectRecycleOrderDetailById(String recycleOrderNo) {
        return recycleCommodityService.list(Wrappers.lambdaQuery(new RecycleCommodity())
                .in(RecycleCommodity::getOrderId, recycleOrderNo));
    }

    @Override
    public AjaxResult addClientServeOrder(ClientServeOrderVO clientServeOrderVO) {

        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(clientServeOrderVO.getClientId());
        ClientAddress clientAddress = clientServeOrderVO.getClientAddress();
        List<RecycleCommodity> recycleCommodityList = clientServeOrderVO.getRecycleCommodityList();
        final String address = clientAddress.getProvince() + clientAddress.getCity() + clientAddress.getArea() + " " + clientAddress.getAddress();
        if (clientAddress.getCity().contains("西藏自治区") ||
                clientAddress.getCity().contains("青海省") ||
                clientAddress.getCity().contains("新疆维吾尔自治区") ||
                clientAddress.getCity().contains("海南省")
        ) {
            return AjaxResult.error("目前暂时不支持当前邮寄地址下单");
        }
        //等于0就是没有综合站，直邮公司
        if (clientServeOrderVO.getMerchantId() == 0) {
            if (CollUtil.isNotEmpty(recycleCommodityList) && recycleCommodityList.size() > 0) {
                //获取公司寄件地址
                List<AdminAddress> sendAddress = adminAddressMapper.getSendAdress(clientAddress.getProvince(), clientAddress.getCity());
                if (sendAddress.size() < 1) {
                    return AjaxResult.error("无可邮寄公司信息，无法下单,请检查地址");
                }
                String orderId = orderNoGenerateUtil.getIncr(OrderInfoConstant.RECYCLE_ORDER);
                AdminAddress adminAddress = sendAddress.get(0);
                //发送快递
                ResultBeanResponse resultBeanResponse = getSendJson(clientAddress, adminAddress, clientServeOrderVO, orderId);

                if (ObjectUtils.isEmpty(resultBeanResponse)) {
                    return AjaxResult.error("向快递公司下单失败，无法下单,请联系管理员处理！");
                }
                if (!resultBeanResponse.getResult()) {
                    return AjaxResult.error("下单失败，失败原因：" + resultBeanResponse.getReason());
                }

                //新建回收订单
                RecycleOrder recycleOrder = getRecycleOrder(orderId, clientServeOrderVO, clientUserManagement, clientAddress, recycleCommodityList, address, resultBeanResponse.getMailNo());
                recycleOrder.setOrderType("快递");
                recycleOrder.setRemark("全国月结，泡比7000，开单务必填写实际重量与尺寸，否则追偿");
                recycleOrderMapper.insert(recycleOrder);

                //新建快递订单信息
                LogisticsExpenditureStatistics logisticsExpenditureStatistics = new LogisticsExpenditureStatistics();
                logisticsExpenditureStatistics.setLogisticsNumber(orderId);
                logisticsExpenditureStatistics.setLogisticsStatus("快递订单");
                logisticsExpenditureStatistics.setConsignTime(clientServeOrderVO.getAppointmentTime());
                //logisticsExpenditureStatistics.setLogisticsCompany(adminAddress.getKuaidi());
                logisticsExpenditureStatistics.setLogisticsCompany("德邦快递");
                logisticsExpenditureStatistics.setLogisticsStatus("1");
                logisticsExpenditureStatistics.setCreatedTime(new Date());
                logisticsExpenditureStatistics.setKuaidinum(resultBeanResponse.getMailNo());
                logisticsExpenditureStatistics.setCreatedBy("admin");
                logisticsExpenditureStatistics.setOrderId(resultBeanResponse.getParentMailNo());
                logisticsExpenditureStatistics.setTaskId(resultBeanResponse.getLogisticID());
                logisticsExpenditureStatistics.setRemark("全国月结，泡比7000，开单务必填写实际重量与尺寸，否则追偿");
                logisticsExpenditureStatisticsMapper.insert(logisticsExpenditureStatistics);

            }
        } else {
            //不等于0就是正常的综合站回收单
            if (CollUtil.isNotEmpty(recycleCommodityList) && recycleCommodityList.size() > 0) {
                //回收订单
                String orderId = orderNoGenerateUtil.getIncr(OrderInfoConstant.RECYCLE_ORDER);

                RecycleOrder recycleOrder = getRecycleOrder(orderId, clientServeOrderVO, clientUserManagement, clientAddress, recycleCommodityList, address, null);
                recycleOrder.setOrderType("综合站");
                recycleOrderMapper.insert(recycleOrder);
            }

            List<HousekeepingCommodity> housekeepingCommodityList = clientServeOrderVO.getHousekeepingCommodityList();
            if (CollUtil.isNotEmpty(housekeepingCommodityList) && housekeepingCommodityList.size() > 0) {
                //家政服务订单
                HousekeepingOrder housekeepingOrder = new HousekeepingOrder();
                String orderId = orderNoGenerateUtil.getIncr(OrderInfoConstant.HOUSEKEEPING_ORDER);
                housekeepingOrder.setHKOrderNo(orderId);
                housekeepingOrder.setAddress(address);
                housekeepingOrder.setClientId(clientUserManagement.getId());
                housekeepingOrder.setPhone(clientUserManagement.getPhone());
                housekeepingOrder.setCreatedTime(new Date());
                housekeepingOrder.setStatus("1");
                BigDecimal forecastMoney = new BigDecimal(0);
                for (HousekeepingCommodity housekeepingCommodity : housekeepingCommodityList) {
                    //服务列表

                    forecastMoney = forecastMoney.add(housekeepingCommodity.getMoney());
                    //商品信息
                    housekeepingCommodity.setHousekeepingId(orderId);
                    housekeepingCommodity.setCreatedBy(clientAddress.getClientName());
                    housekeepingCommodityMapper.insert(housekeepingCommodity);
                }
                housekeepingOrder.setCreatedBy(clientAddress.getClientName());
                housekeepingOrder.setForecastMoney(forecastMoney);
                housekeepingOrder.setRemark(clientServeOrderVO.getRemark());
                housekeepingOrder.setMerchantId(clientServeOrderVO.getMerchantId());
                housekeepingOrder.setAppointmentTime(clientServeOrderVO.getAppointmentTime());

                housekeepingOrderMapper.insert(housekeepingOrder);
            }

        }

        return AjaxResult.success("下单成功");
    }


    private ResultBeanResponse getSendJson(ClientAddress clientAddress, AdminAddress adminAddress, ClientServeOrderVO clientServeOrderVO, String orderId) {
        ResultBeanResponse resultBeanResponse = new ResultBeanResponse();
        BigDecimal forecastWeight = new BigDecimal(0);
        String cargoName = "";
        List<RecycleCommodity> recycleCommodityList = clientServeOrderVO.getRecycleCommodityList();
        for (RecycleCommodity recycleCommodity : recycleCommodityList) {
            //回收物品
            //订单预估总重
            forecastWeight = forecastWeight.add(recycleCommodity.getForecastWeight());
            //货物名字
            if (!cargoName.contains(recycleCommodity.getRecycleType())) {
                cargoName = cargoName + recycleCommodity.getRecycleType();
            }
        }
        final String adminAddressDetail = adminAddress.getProvince() + adminAddress.getCity() + adminAddress.getArea() + " " + adminAddress.getAddress();
        //封装请求JSON
        NameValuePair[] sendObject = getJsonObject(clientAddress, adminAddress, orderId, forecastWeight, cargoName, adminAddressDetail, clientServeOrderVO);
        try {
            //请求url
            ResultDO<String> response = null;
            //返回结果
            response = HttpUtils.sendRequest(DEPPON_URL, sendObject, "UTF-8", 5000);
            Gson gson = new Gson();
            ResultBeanResponse result = gson.fromJson(response.getModel(), ResultBeanResponse.class);
            //记录快递发送日志
            recycleRequestLogService.save(new RecycleRequestLog().
                    setRequestData(sendObject.toString()).
                    setResponseData(result.toString()).
                    setRemark("寄件接口").
                    setLogType("寄件接口").
                    setCreateBy("ADMIN").
                    setCreateDate(new Date()).
                    setRequestUser("蓝星人").
                    setResponseUser("德邦"));
            return result;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return resultBeanResponse;
    }

    private NameValuePair[] getJsonObject(ClientAddress clientAddress, AdminAddress adminAddress, String orderId, BigDecimal forecastWeight, String cargoName, String adminAddressDetail, ClientServeOrderVO clientServeOrderVO) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //基本信息
        JsonRootBean jsonRootBean = new JsonRootBean();
        jsonRootBean.setLogisticID(SIGN + orderId);
        jsonRootBean.setCustOrderNo(orderId);
        jsonRootBean.setNeedTraceInfo(1);
        jsonRootBean.setCompanyCode(COMPANY_CODE);
        jsonRootBean.setOrderType("1");
        jsonRootBean.setTransportType(TRANSPORT_TYPE);
        jsonRootBean.setCustomerCode(CUSTOMER_CODE);
        jsonRootBean.setGmtCommit(simpleDateFormat.format(new Date()));
        jsonRootBean.setPayType("2");
        jsonRootBean.setIsOut("N");
        jsonRootBean.setSendStartTime(simpleDateFormat.format(clientServeOrderVO.getAppointmentTime()));
        jsonRootBean.setSendEndTime(simpleDateFormat.format(clientServeOrderVO.getAppointmentTimeEnd()));
        jsonRootBean.setRemark("全国月结，泡比7000，开单务必填写实际重量与尺寸，否则追偿");
        //货物信息
        PackageInfo packageInfo = new PackageInfo();
        packageInfo.setCargoName(cargoName);
        packageInfo.setTotalNumber(1);
        packageInfo.setTotalWeight(forecastWeight);
        packageInfo.setDeliveryType("2");
        jsonRootBean.setPackageInfo(packageInfo);
        //收件人信息
        Receiver receiver = new Receiver();
        receiver.setName(adminAddress.getAdminName());
        receiver.setPhone(adminAddress.getPhone());
        receiver.setMobile(adminAddress.getPhone());
        receiver.setProvince(adminAddress.getProvince());
        receiver.setCity(adminAddress.getCity());
        receiver.setCounty(adminAddress.getArea());
        receiver.setAddress(adminAddressDetail);
        receiver.setCompanyName("蓝星人");
        jsonRootBean.setReceiver(receiver);
        //发货人信息
        Sender sender = new Sender();
        sender.setName(clientAddress.getClientName());
        sender.setMobile(clientAddress.getPhone());
        sender.setProvince(clientAddress.getProvince());
        sender.setCity(clientAddress.getCity());
        sender.setCounty(clientAddress.getArea());
        sender.setAddress(clientAddress.getAddress());
        jsonRootBean.setSender(sender);

        Long timestamp = System.currentTimeMillis();
        String params = FastJsonUtil.toJSONString(jsonRootBean);
        String digest = getDigest(params + APP_KEY + timestamp);
        NameValuePair[] data = new NameValuePair[4];
        data[0] = new NameValuePair("companyCode", COMPANY_CODE);
        data[1] = new NameValuePair("digest", digest);
        data[2] = new NameValuePair("timestamp", timestamp.toString());
        data[3] = new NameValuePair("params", params);
        return data;
    }

    private RecycleOrder getRecycleOrder(String orderId, ClientServeOrderVO clientServeOrderVO, ClientUserManagement clientUserManagement, ClientAddress clientAddress, List<RecycleCommodity> recycleCommodityList, String address, String kuaidinum) {

        RecycleOrder recycleOrder = new RecycleOrder();
        recycleOrder.setRecycleOrderNo(orderId);
        recycleOrder.setPhone(clientAddress.getPhone());
        recycleOrder.setCreatedTime(new Date());
        recycleOrder.setAppointmentTime(clientServeOrderVO.getAppointmentTime());
        recycleOrder.setAppointmentTimeEnd(clientServeOrderVO.getAppointmentTimeEnd());
        recycleOrder.setAddress(address);
        recycleOrder.setVisitTime(clientServeOrderVO.getAppointmentTime());
        BigDecimal forecastWeight = new BigDecimal(0);
        for (RecycleCommodity recycleCommodity : recycleCommodityList) {
            //回收物品
            if (StringUtils.isBlank(recycleCommodity.getRecycleType())) {
                recycleCommodity.setRecycleType("杂物");
            }
            //订单预估总重
            forecastWeight = forecastWeight.add(recycleCommodity.getForecastWeight());
            //商品信息
            recycleCommodity.setOrderId(orderId);
            recycleCommodity.setCreatedBy(clientAddress.getClientName());
            recycleCommodityMapper.insert(recycleCommodity);
        }
        //预估重量
        recycleOrder.setForecastWeight(forecastWeight);
        recycleOrder.setStatus("1");
        recycleOrder.setKuaidinum(kuaidinum);
        recycleOrder.setRemark(clientServeOrderVO.getRemark());
        recycleOrder.setCreatedBy(clientAddress.getClientName());
        recycleOrder.setClientId(clientServeOrderVO.getClientId());
        recycleOrder.setMerchantId(clientServeOrderVO.getMerchantId());
        return recycleOrder;
    }


    @Override
    public void updateRecycleCommodityList(List<RecycleCommodity> recycleCommodityList) {
        recycleCommodityService.updateBatchById(recycleCommodityList);

    }

    @Override
    public SynchronousDeBangStatus expressageCallback(MultiValueMap<String, String> formData) {
        SynchronousDeBangStatus result = new SynchronousDeBangStatus();
        String paramsValue = formData.getFirst("params");
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JsonNode paramsJson = objectMapper.readTree(paramsValue);
            String statusType = paramsJson.get("statusType").asText();
            String logisticID = paramsJson.get("logisticID").asText();
            if (StringUtils.isBlank(statusType) || StringUtils.isBlank(logisticID)) {
                result.setLogisticCompanyID(COMPANY_CODE);
                result.setReason("失败:缺失：statusType或logisticID");
                result.setResultCode("500");
                result.setResult("false");
            } else {
                LogisticsExpenditureStatistics logisticsExpenditureStatistics = logisticsExpenditureStatisticsMapper.selectOne(new LambdaQueryWrapper<LogisticsExpenditureStatistics>().eq(LogisticsExpenditureStatistics::getTaskId, logisticID));
                if (ObjectUtils.isEmpty(logisticsExpenditureStatistics)) {
                    result.setLogisticCompanyID(COMPANY_CODE);
                    result.setReason("失败:logisticID在蓝星人系统中不存在");
                    result.setResultCode("500");
                    result.setResult("false");
                } else {
                    if ("RECEIPTING".equals(statusType)) {
                        //接货中
                        getCourier(paramsJson.get("comments").asText(), logisticsExpenditureStatistics);
                        logisticsExpenditureStatistics.setLogisticsStatus("接货中");
                        logisticsExpenditureStatisticsMapper.updateById(logisticsExpenditureStatistics);
                        //更新回收订单状态
                        RecycleOrder recycleOrder = getById(logisticsExpenditureStatistics.getLogisticsNumber());
                        recycleOrder.setStatus("2");
                        updateById(recycleOrder);
                    } else if ("GOT".equals(statusType)) {
                        //更新回收订单状态
                        RecycleOrder recycleOrder = getById(logisticsExpenditureStatistics.getLogisticsNumber());
                        logisticsExpenditureStatistics.setLogisticsStatus("已取件");
                        String totalWeight = paramsJson.get("totalWeight").asText();
                        String totalPrice = paramsJson.get("totalPrice").asText();
                        String totalVolume = paramsJson.get("totalVolume").asText();
                        if (StringUtils.isNotBlank(totalWeight) && !"null".equals(totalWeight)) {
                            logisticsExpenditureStatistics.setWeight(new BigDecimal(totalWeight));
                            recycleOrder.setPracticalWeight(new BigDecimal(totalWeight));
                        }
                        if (StringUtils.isNotBlank(totalVolume) && !"null".equals(totalVolume)) {
                            logisticsExpenditureStatistics.setVolume(new BigDecimal(totalVolume));
                            recycleOrder.setVolume(new BigDecimal(totalVolume));
                        }
                        if (StringUtils.isNotBlank(totalPrice) && !"null".equals(totalPrice)) {
                            logisticsExpenditureStatistics.setMoney(new BigDecimal(totalPrice));
                        }
                        logisticsExpenditureStatisticsMapper.updateById(logisticsExpenditureStatistics);
                        recycleOrder.setStatus("3");
                        recycleOrder.setVisitTime(new Date());
                        updateById(recycleOrder);
                    } else if ("SIGNSUCCESS".equals(statusType)) {
                        String totalPrice = paramsJson.get("totalPrice").asText();
                        if (StringUtils.isNotBlank(totalPrice) && !"null".equals(totalPrice)) {
                            logisticsExpenditureStatistics.setMoney(new BigDecimal(totalPrice));
                        }
                        logisticsExpenditureStatistics.setLogisticsStatus("已签收");
                        logisticsExpenditureStatisticsMapper.updateById(logisticsExpenditureStatistics);
                        //更新回收订单状态
                        RecycleOrder recycleOrder = getById(logisticsExpenditureStatistics.getLogisticsNumber());
                        recycleOrder.setStatus("4");
                        updateById(recycleOrder);
                    } else if ("REJECT".equals(statusType) || "CANCEL".equals(statusType) || "FAILGOT".equals(statusType) || "GOBACK".equals(statusType)) {
                        //取货失败场景
                        String comments = paramsJson.get("comments").asText();
                        logisticsExpenditureStatistics.setLogisticsStatus("已取消");
                        logisticsExpenditureStatisticsMapper.updateById(logisticsExpenditureStatistics);
                        //更新回收订单状态
                        RecycleOrder recycleOrder = getById(logisticsExpenditureStatistics.getLogisticsNumber());
                        recycleOrder.setStatus("7");
                        updateById(recycleOrder);
                    }
                    result.setLogisticCompanyID(COMPANY_CODE);
                    result.setLogisticID(logisticID);
                    result.setReason("成功");
                    result.setResultCode("1000");
                    result.setResult("true");
                }
            }
        } catch (Exception e) {
            log.error("异常:" + e.getMessage(), e);
            // 处理解析异常
            e.printStackTrace();
            result.setLogisticCompanyID(COMPANY_CODE);
            result.setLogisticID("");
            result.setReason("失败，失败原因是：" + e.getMessage());
            result.setResultCode("500");
            result.setResult("false");
        }
        recycleRequestLogService.save(new RecycleRequestLog().
                setRequestData(formData.toString()).
                setResponseData(new JSONObject(result).toString()).
                setRemark("德邦快递订单状态推送接口").
                setLogType("德邦快递订单状态推送接口").
                setCreateBy("ADMIN").
                setCreateDate(new Date()).
                setRequestUser("德邦快递").
                setResponseUser("蓝星人"));
        return result;

    }

    private void getCourier(String comments, LogisticsExpenditureStatistics logisticsExpenditureStatistics) {
        String pattern = "^(接货)中(.*)(\\d{11})$"; // 使用正则表达式匹配输入格式
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        // 现在创建 matcher 对象
        Matcher m = r.matcher(comments);
        if (m.find()) {
            String name = m.group(2); // 第二个捕获组为 "骆冰山"
            String phoneNumber = m.group(3); // 第三个捕获组为 "16626330598"
            logisticsExpenditureStatistics.setCourier(name);
            logisticsExpenditureStatistics.setCourierPhone(phoneNumber);
        } else {
            logisticsExpenditureStatistics.setUpdatedBy("更新快递员信息失败，请注意检查日志");
        }
    }

    /***
     *  确认收货
     */
    @Override
    public AjaxResult confirmReceipt(String orderId) {

        //修改订单状态
        RecycleOrder recycleOrder = recycleOrderMapper.selectOne(new LambdaQueryWrapper<>(new RecycleOrder()).eq(RecycleOrder::getRecycleOrderNo, orderId));
        recycleOrder.setStatus("6");
        //TODO 应蔡总要求，目前不再计算积分与分红
        recycleOrderMapper.updateById(recycleOrder);
//        List<RecycleCommodity> recycleCommodities = recycleCommodityMapper.selectList(new LambdaQueryWrapper<>(new RecycleCommodity()).eq(RecycleCommodity::getOrderId, orderId));
//        BigDecimal practicalWeight = new BigDecimal(BigInteger.ZERO);
//        Integer integral = 0;
//        if (ObjectUtils.isEmpty(recycleOrder.getKuaidinum())) {
//            //综合站订单
//            //结算订单所得积分
//            for (RecycleCommodity recycleCommodity : recycleCommodities) {
//                //根据类型获取每KG多少钱
//                List<PriceSetting> priceSettings = priceSettingMapper.selectList(new LambdaQueryWrapper<>(new PriceSetting()).eq(PriceSetting::getCategory, recycleCommodity.getRecycleType()).eq(PriceSetting::getMerchantId, recycleOrder.getMerchantId()));
//                if (priceSettings.size() < 0) {
//                    MerchantManagement merchantManagement = merchantManagementMapper.selectById(recycleOrder.getMerchantId());
//                    return AjaxResult.error("综合站：" + merchantManagement.getMerchantName() + "未设置：" + recycleCommodity.getRecycleType() + "的价格，请联系综合站处理");
//                }
//                IntegralConfig integralConfig = integralConfigMapper.selectById(1);
//                PriceSetting priceSetting = priceSettings.get(0);
//                //回收货物总价
//                BigDecimal scale = priceSetting.getPrice().multiply(recycleCommodity.getPracticalWeight()).setScale(2, BigDecimal.ROUND_HALF_UP);
//                Integer recycleCommodityIntegral = Integer.parseInt(scale.multiply(new BigDecimal(integralConfig.getIntegral())).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
//
//                integral += recycleCommodityIntegral;
//            }
//
//        } else {
//            //快递订单
//            //结算订单所得积分
//            for (RecycleCommodity recycleCommodity : recycleCommodities) {
//                //根据类型获取每KG多少钱
//                List<SysTypeConfig> sysTypeConfigList = sysTypeConfigMapper.selectList(new LambdaQueryWrapper<>(new SysTypeConfig()).eq(SysTypeConfig::getName, recycleCommodity.getRecycleType()).eq(SysTypeConfig::getType, "回收分类"));
//                if (sysTypeConfigList.size() < 0) {
//                    return AjaxResult.error("公司快递回收未设置：" + recycleCommodity.getRecycleType() + "的价格，请前往系统配置设置");
//                }
//                IntegralConfig integralConfig = integralConfigMapper.selectById(1);
//                SysTypeConfig sysTypeConfig = sysTypeConfigList.get(0);
//                //回收货物总价
//                BigDecimal scale = sysTypeConfig.getMoney().multiply(recycleCommodity.getPracticalWeight()).setScale(2, BigDecimal.ROUND_HALF_UP);
//                Integer recycleCommodityIntegral = Integer.parseInt(scale.multiply(new BigDecimal(integralConfig.getIntegral())).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
//
//                integral += recycleCommodityIntegral;
//
//                practicalWeight = practicalWeight.add(recycleCommodity.getPracticalWeight());
//
//            }
//
//        }
//
//        //触发结算积分给用户
//        recycleOrder.setPracticalWeight(practicalWeight);
//        recycleOrder.setIntegral(integral);
//        recycleOrderMapper.updateById(recycleOrder);
//
//        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(recycleOrder.getClientId());
//        clientUserManagement.setIntegral(clientUserManagement.getIntegral() + integral);
//        clientUserManagementMapper.updateById(clientUserManagement);
//
//        //记录用户回收得到积分以及更新用户积分数量
//        extracted(orderId, integral, clientUserManagement.getId().intValue(), 1, 2);
//
//        //触发分红
//        shareOutBonus(recycleOrder, clientUserManagement);

        return AjaxResult.success();
    }

    private void extracted(String orderId, Integer integral, Integer userId, Integer userType, Integer type) {
        BillRecord billRecord = new BillRecord();
        billRecord.setOrderNo(orderId);
        billRecord.setCreateTime(new Date());
        billRecord.setIncome(BigDecimal.valueOf(integral));
        billRecord.setUserId(Long.valueOf(userId));
        billRecord.setUserType(userType);
        billRecord.setType(type);
        merchatBillRecordMapper.insert(billRecord);
    }

    @Override
    public void shareOutBonus(RecycleOrder recycleOrder, ClientUserManagement clientUserManagement) {

        //首先是是否存在业务员分红
        if (!ObjectUtils.isEmpty(clientUserManagement.getSalesmanId())) {
            //1.获取业务员的分红比例，根据订单的积分四舍五入分到业务员手上
            SalesmanManagement salesmanManagement = salesmanManagementMapper.selectById(clientUserManagement.getSalesmanId());

            IntegralConfig salesmanIntegralConfig = integralConfigMapper.selectOne(new LambdaQueryWrapper<IntegralConfig>().eq(IntegralConfig::getType, "2").eq(IntegralConfig::getName, "业务员提成规则"));

            Integer salesmanShareOutBonus = Math.toIntExact(recycleOrder.getIntegral() * salesmanIntegralConfig.getIntegral() / 100);

            //2.记录业务员分红数据
            extracted(recycleOrder.getRecycleOrderNo(), salesmanShareOutBonus, salesmanManagement.getId().intValue(), 4, 1);

            //3.更新业务员的积分数量
            salesmanManagement.setIntegral(salesmanManagement.getIntegral() + salesmanShareOutBonus);
            salesmanManagementMapper.updateById(salesmanManagement);
        }


        //引流门店或上级用户分红（二者只能存在其一）
        //获取引流门店/上级用户的分红比例，根据订单的积分四舍五入分到引流门店/上级用户手上
        if (!ObjectUtils.isEmpty(clientUserManagement.getSuperiorId())) {
            IntegralConfig superiorIntegralConfig = integralConfigMapper.selectOne(new LambdaQueryWrapper<IntegralConfig>().eq(IntegralConfig::getType, "4").eq(IntegralConfig::getName, "达人提成规则"));
            ClientUserManagement superior = clientUserManagementMapper.selectById(clientUserManagement.getSuperiorId());

            //2.记录上级用户分红数据
            Integer superiorShareOutBonus = Math.toIntExact(recycleOrder.getIntegral() * superiorIntegralConfig.getIntegral() / 100);

            extracted(recycleOrder.getRecycleOrderNo(), superiorShareOutBonus, superior.getId().intValue(), 4, 1);

            //3.更新上级用户数据
            superior.setIntegral(superior.getIntegral() + superiorShareOutBonus);
            clientUserManagementMapper.updateById(superior);

        } else if (!ObjectUtils.isEmpty(clientUserManagement.getShopId())) {
            IntegralConfig shopIntegralConfig = integralConfigMapper.selectOne(new LambdaQueryWrapper<IntegralConfig>().eq(IntegralConfig::getType, "3").eq(IntegralConfig::getName, "门店提成规则"));

            ShopManagement shopManagement = shopManagementMapper.selectById(clientUserManagement.getShopId());

            //2.记录引流门店分红数据
            Integer shopShareOutBonus = Math.toIntExact(recycleOrder.getIntegral() * shopIntegralConfig.getIntegral() / 100);

            extracted(recycleOrder.getRecycleOrderNo(), shopShareOutBonus, shopManagement.getId().intValue(), 3, 1);

            //3.更新引流门店数据
            shopManagement.setIntegral(shopManagement.getIntegral() + shopShareOutBonus);
            shopManagementMapper.updateById(shopManagement);
        }

    }

    @Override
    public AjaxResult culateRecycleOrderIntegral(List<RecycleCommodity> recycleCommodityList) {

        Integer integral = 0;

        for (RecycleCommodity recycleCommodity : recycleCommodityList) {

            List<SysTypeConfig> sysTypeConfigList = sysTypeConfigMapper.selectList(new LambdaQueryWrapper<>(new SysTypeConfig()).eq(SysTypeConfig::getName, recycleCommodity.getRecycleType()).eq(SysTypeConfig::getType, "回收分类"));
            if (sysTypeConfigList.size() < 1) {
                return AjaxResult.error("公司快递回收未设置：" + recycleCommodity.getRecycleType() + "的价格，请前往系统配置设置");
            }
            IntegralConfig integralConfig = integralConfigMapper.selectById(1);
            SysTypeConfig sysTypeConfig = sysTypeConfigList.get(0);
            //回收货物总价
            BigDecimal scale = sysTypeConfig.getMoney().multiply(recycleCommodity.getPracticalWeight()).setScale(2, BigDecimal.ROUND_HALF_UP);
            Integer recycleCommodityIntegral = Integer.parseInt(scale.multiply(new BigDecimal(integralConfig.getIntegral())).setScale(0, BigDecimal.ROUND_HALF_UP).toString());

            integral += recycleCommodityIntegral;
        }

        return AjaxResult.success(integral);
    }

    @Override
    public BigDecimal sumFinishedOrder(LambdaQueryWrapper<RecycleOrder> wrapper) {
        return getBaseMapper().sumFinishedOrder(wrapper);
    }

    @Override
    public AjaxResult miniClientGetClientRecycleOrder(RecycleOrderDTO queryDTO) {
        final RecycleOrder recycleOrder = new RecycleOrder();
        BeanUtils.copyProperties(queryDTO, recycleOrder);
        final LambdaQueryWrapper<RecycleOrder> wrapper = Wrappers.lambdaQuery(recycleOrder);
        if (queryDTO.getSearchTimeBegin() != null) {
            wrapper.ge(RecycleOrder::getCreatedTime, queryDTO.getSearchTimeBegin());
        }
        if (queryDTO.getSearchTimeEnd() != null) {
            wrapper.le(RecycleOrder::getCreatedTime, queryDTO.getSearchTimeEnd());
        }
        wrapper.orderByDesc(RecycleOrder::getCreatedTime);
        IPage<RecycleOrder> recycleOrderPage = page(new Page<>(queryDTO.getCurrentPage(), queryDTO.getPageSize(), true), wrapper);

        List<RecycleOrder> records = recycleOrderPage.getRecords();
        List<String> orderNoList = records.stream().map(RecycleOrder::getRecycleOrderNo).collect(Collectors.toList());
        List<ClientPrayerManagement> clientPrayerManagements = clientPrayerManagementMapper.selectList(new LambdaQueryWrapper<ClientPrayerManagement>().in(ClientPrayerManagement::getRecycleOrderId, orderNoList));
        List<LogisticsExpenditureStatistics> logisticsExpenditureStatisticsList = logisticsExpenditureStatisticsMapper.selectList(new LambdaQueryWrapper<LogisticsExpenditureStatistics>().in(LogisticsExpenditureStatistics::getLogisticsNumber, orderNoList));
        Page<RecycleOrderVO> recycleOrderVOPage = new Page<>(queryDTO.getCurrentPage(), queryDTO.getPageSize());
        List<RecycleOrderVO> recycleOrderVOArrayList = new ArrayList<>();
        for (RecycleOrder record : records) {
            RecycleOrderVO recycleOrderVO = new RecycleOrderVO();
            BeanUtils.copyProperties(record, recycleOrderVO);
            List<RecycleCommodity> recycleCommodities = selectRecycleOrderDetailById(record.getRecycleOrderNo());
            if (recycleCommodities.size() > 0) {
                String s = "";
                for (RecycleCommodity recycleCommodity : recycleCommodities) {
                    s = s + recycleCommodity.getRecycleType() + " ";
                }
                recycleOrderVO.setRecycleOrderService(s);
                recycleOrderVO.setLinkman(record.getCreatedBy() + " " + record.getPhone());
            }
            List<ClientPrayerManagement> collect = clientPrayerManagements.stream().filter(p -> record.getRecycleOrderNo().equals(p.getRecycleOrderId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                recycleOrderVO.setPrayerDetail(collect.get(0).getDetail());
                recycleOrderVO.setPrayerTime(collect.get(0).getCreatedTime());
            }
            List<LogisticsExpenditureStatistics> logisticsExpenditureStatistics = logisticsExpenditureStatisticsList.stream().filter(l -> record.getRecycleOrderNo().equals(l.getLogisticsNumber())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(logisticsExpenditureStatistics)) {
                recycleOrderVO.setCourier(logisticsExpenditureStatistics.get(0).getCourier());
                recycleOrderVO.setCourierPhone(logisticsExpenditureStatistics.get(0).getCourierPhone());
            }
            recycleOrderVOArrayList.add(recycleOrderVO);
        }
        recycleOrderVOPage.setRecords(recycleOrderVOArrayList);

        List<SysTypeConfig> sysTypeConfigList = sysTypeConfigMapper.selectList(new LambdaQueryWrapper<SysTypeConfig>().eq(SysTypeConfig::getType, "回收分类"));


        return AjaxResult.success(recycleOrderVOPage).put("recycle", sysTypeConfigList);

    }

    @Override
    public AjaxResult wbkTest(JsonRootBean getJson) {

        try {
            Long timestamp = System.currentTimeMillis();
            String params = FastJsonUtil.toJSONString(getJson);
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            System.out.println("format = " + format);
            String digest = getDigest(params + APP_KEY + timestamp);
            NameValuePair[] data = new NameValuePair[4];
            data[0] = new NameValuePair("companyCode", COMPANY_CODE);
            data[1] = new NameValuePair("digest", digest);
            data[2] = new NameValuePair("timestamp", timestamp.toString());
            data[3] = new NameValuePair("params", params);
            //请求url
            ResultDO<String> response = null;
            //返回结果
            response = HttpUtils.sendRequest(DEPPON_URL, data, "UTF-8", 5000);
            String model = response.getModel();
            Gson gson = new Gson();
            ResultBeanResponse result = gson.fromJson(model, ResultBeanResponse.class);
            return AjaxResult.success(result);
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    private static String getDigest(String plainText) {
        return Base64.encodeBase64String(DigestUtils.md5Hex(plainText).getBytes());
    }


    @Override
    public IPage<RecycleOrderVO> selectOrderPage(RecycleOrderDTO queryDTO) throws Exception{
        final RecycleOrder recycleOrder = new RecycleOrder();
        BeanUtils.copyProperties(queryDTO, recycleOrder);
        final LambdaQueryWrapper<RecycleOrder> wrapper = Wrappers.lambdaQuery(recycleOrder);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat old = new SimpleDateFormat("yyyy-MM-dd");
        if (queryDTO.getSearchTimeBegin() != null) {
            wrapper.ge(RecycleOrder::getCreatedTime, simpleDateFormat.parse(old.format(queryDTO.getSearchTimeBegin()) + " 00:00:00"));
        }
        if (queryDTO.getSearchTimeEnd() != null) {
            wrapper.le(RecycleOrder::getCreatedTime, simpleDateFormat.parse(old.format(queryDTO.getSearchTimeEnd()) + " 23:59:59"));
        }
        if (StringUtils.isNotBlank(queryDTO.getPracticalWeight()) && isValidBigDecimal(queryDTO.getPracticalWeight())) {
            wrapper.ge(RecycleOrder::getPracticalWeight, queryDTO.getPracticalWeight());
        }
        if (StringUtils.isNotBlank(queryDTO.getPracticalWeightEnd()) && isValidBigDecimal(queryDTO.getPracticalWeightEnd())) {
            wrapper.le(RecycleOrder::getPracticalWeight, queryDTO.getPracticalWeightEnd());
        }
        wrapper.orderByDesc(RecycleOrder::getCreatedTime);

        Page<RecycleOrder> page = this.page(new Page<RecycleOrder>()
                .setCurrent(queryDTO.getCurrentPage())
                .setSize(queryDTO.getPageSize()), wrapper);
        List<String> orderNoList = page.getRecords().stream().map(RecycleOrder::getRecycleOrderNo).collect(Collectors.toList());
        Page<RecycleOrderVO> recycleOrderVOPage = new Page<>(queryDTO.getCurrentPage(), queryDTO.getPageSize());
        List<RecycleOrderVO> recycleOrderVOArrayList = new ArrayList<>();
        List<LogisticsExpenditureStatistics> logisticsExpenditureStatisticsList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(orderNoList)) {
             logisticsExpenditureStatisticsList = logisticsExpenditureStatisticsMapper.selectList(new LambdaQueryWrapper<LogisticsExpenditureStatistics>().in(LogisticsExpenditureStatistics::getLogisticsNumber, orderNoList));
        }
        for (RecycleOrder record : page.getRecords()) {
            RecycleOrderVO recycleOrderVO = new RecycleOrderVO();
            BeanUtils.copyProperties(record, recycleOrderVO);
            if (CollectionUtils.isNotEmpty(logisticsExpenditureStatisticsList) && logisticsExpenditureStatisticsList.size() > 0) {
                List<LogisticsExpenditureStatistics> logisticsExpenditureStatistics = logisticsExpenditureStatisticsList.stream().filter(l -> record.getRecycleOrderNo().equals(l.getLogisticsNumber())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(logisticsExpenditureStatistics)) {
                    recycleOrderVO.setCourier(logisticsExpenditureStatistics.get(0).getCourier());
                    recycleOrderVO.setCourierPhone(logisticsExpenditureStatistics.get(0).getCourierPhone());
                }
            }
            recycleOrderVOArrayList.add(recycleOrderVO);
        }
        recycleOrderVOPage.setRecords(recycleOrderVOArrayList);
        recycleOrderVOPage.setTotal(page.getTotal());

        return recycleOrderVOPage;
    }

    @Override
    public AjaxResult recycleOrderTotalMoney(RecycleOrderDTO queryDTO) {
        //封装请求参数
        final RecycleOrder recycleOrder = new RecycleOrder();
        BeanUtils.copyProperties(queryDTO, recycleOrder);
        final LambdaQueryWrapper<RecycleOrder> wrapper = Wrappers.lambdaQuery(recycleOrder);
        if (queryDTO.getSearchTimeBegin() != null) {
            wrapper.ge(RecycleOrder::getCreatedTime, queryDTO.getSearchTimeBegin());
        }
        if (queryDTO.getSearchTimeEnd() != null) {
            wrapper.le(RecycleOrder::getCreatedTime, queryDTO.getSearchTimeEnd());
        }
        wrapper.orderByDesc(RecycleOrder::getCreatedTime);
        //额外封装总的物流金额
        List<RecycleOrder> list = this.list(wrapper.select(RecycleOrder::getRecycleOrderNo));
        List<String> recycleOrderNoList = list.stream().map(RecycleOrder::getRecycleOrderNo).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(recycleOrderNoList)){
            return AjaxResult.success(new BigDecimal("0"));
        }
        List<LogisticsExpenditureStatistics> logisticsExpenditureStatistics = logisticsExpenditureStatisticsMapper.
                selectList(new LambdaQueryWrapper<LogisticsExpenditureStatistics>().
                        in(LogisticsExpenditureStatistics::getLogisticsNumber, recycleOrderNoList).
                        select(LogisticsExpenditureStatistics::getMoney));
        BigDecimal totalMoney = new BigDecimal("0");
        for (LogisticsExpenditureStatistics l : logisticsExpenditureStatistics) {
            totalMoney = totalMoney.add(l.getMoney() != null ? l.getMoney() : BigDecimal.ZERO);
        }

        return AjaxResult.success(totalMoney);
    }


    public static boolean isValidBigDecimal(String input) {
        try {
            new BigDecimal(input);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
